﻿using NextEngine.PortInterface;
using System;
using System.Net;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage.Streams;

namespace KouDai.WinPad.ImplInterface
{
    public class WinRTAESEncryptor : IAESEncryptor
    {
        public string AESEncrypt(string dataToEncrypt, string key, string salt)
        {
            // Get the key hash (you can as well use the binary of the key string)
            byte[] bytes = string2Byte(key);
            IBuffer buffer = WindowsRuntimeBufferExtensions.AsBuffer(bytes, 0, bytes.Length);

            // Create a buffer that contains the encoded message to be encrypted. 
            var toDecryptBuffer = CryptographicBuffer.ConvertStringToBinary(dataToEncrypt, BinaryStringEncoding.Utf8);

            // Open a symmetric algorithm provider for the specified algorithm. 
            var aes = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);

            // Create a symmetric key.
            var symetricKey = aes.CreateSymmetricKey(buffer);

            //Create a iv
            byte[] ivBytes = Encoding.UTF8.GetBytes("0102030405060708");
            IBuffer ivBuffer = WindowsRuntimeBufferExtensions.AsBuffer(ivBytes, 0, ivBytes.Length);

            // The input key must be securely shared between the sender of the cryptic message
            // and the recipient. The initialization vector must also be shared but does not
            // need to be shared in a secure manner. If the sender encodes a message string 
            // to a buffer, the binary encoding method must also be shared with the recipient.
            var buffEncrypted = CryptographicEngine.Encrypt(symetricKey, toDecryptBuffer, ivBuffer);

            // Convert the encrypted buffer to a string (for display).
            // We are using Base64 to convert bytes to string since you might get unmatched characters
            // in the encrypted buffer that we cannot convert to string with UTF8.
            var strEncrypted = CryptographicBuffer.EncodeToBase64String(buffEncrypted);

            return WebUtility.UrlEncode(strEncrypted);
        }

        public static byte[] string2Byte(String str)
        {
            byte[] result = new byte[str.Length / 2];
            for (int i = 0; i < result.Length; i++)
            {
                byte b = (byte)((((getStrIndex(str[2 * i])) & 0x0f) << 4) | ((getStrIndex(str[2 * i + 1])) & 0x0f));
                result[i] = b;
            }
            return result;
        }

        public static int getStrIndex(char c)
        {
            if (c > '9')
            {
                return 10 + (c - 'a');
            }
            else
            {
                return c - '0';
            }
        }
    }
}
